package com.pudu.pdrobot;

import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.pudu.mydemo.entity.ClientThread;
import com.pudu.mydemo.entity.LogFileThread;
import com.pudu.mydemo.entity.ServerThread;
import com.pudu.mydemo.entity.TcpReceiverThread;
import com.pudu.mydemo.entity.TcpStringEntity;
import com.pudu.mydemo.remote.ApiHttpClient;
import com.pudu.mydemo.utils.MLog;
import com.pudu.mydemo.utils.RobotFileUtils;
import com.pudu.mydemo.utils.SpUtils;
import com.pudu.pudusclient.CANDataService;
import com.pudu.pudusclient.CanbusDataSaveThread;
import com.pudu.pudusclient.ControlServiceService;
import com.pudu.pudusclient.CustomTemplate;
import com.pudu.pudusclient.HLSRadarService;
import com.pudu.pudusclient.LTSService;
import com.pudu.pudusclient.RadarUsbService;
import com.pudu.pudusclient.RobotSetService;
import com.tencent.bugly.crashreport.CrashReport;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;

public class App extends Application{

	static{
		System.loadLibrary("MyDemo");
	}

	static Context _context;
	static String RobotSerialID = "";
	public static App instance;

	//———APP合并————
	public static String MYTAG = "PUDUROBOT";
	public ControlServiceService myService;
    //———APP合并————

	private Thread cThread;
	private Thread sThread;
	private Thread tcpTherad;
	private LogFileThread logThread;
	private boolean threadIsLived = true;
	public static boolean isUpdate = true;
	private TcpStringEntity tcpStringEntity = TcpStringEntity.getInstance();

	//保存CAN bus 日志线程 Handler
	CanbusDataSaveThread mBusDataSaveThread;

	@Override
	public void onCreate() {
		super.onCreate();
		

		Log.i(MYTAG,"current thread: "+Thread.currentThread().getId());
		instance = this;
		_context = getApplicationContext();

		setRobotSerialID();

		//创建日志文件夹
		initLogDir();
		initData();
		initThread();
//		LeakCanary.install(this);
		init();
		/**
		 * for test 测试数据
		 */
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		MLog.d("APP","app init");

		//———APP合并————
		Intent bindingIntent = new Intent(this, LTSService.class);
		startService(bindingIntent);

		Intent setServiceIntent = new Intent(this, RobotSetService.class);
		startService(setServiceIntent);

		//初始化template数据
		CustomTemplate.getInstance().initData();

		bindService(bindingIntent, LTSConnection, Context.BIND_AUTO_CREATE);
		StartCanbusService();
		//———APP合并————
		//启动电量监听服务
//		startService(new Intent(this, BatteryService.class));

		if(mRadarType == 0) {
			Intent startService = new Intent(this, RadarUsbService.class);
			startService(startService);
			Log.i("12345", "RadarUsbService");
		}else{
			Intent startService = new Intent(this, HLSRadarService.class);
			startService(startService);
		}


	}

	public int mRadarType = 1;
	//0  2000 元的激光雷达
	//1  HLS 200元的韩国激光雷达
	public int mHlsVersion = 2;
	// HLS固件有两个版本，最早到货的一个设备 =1是1.0版本
	// 新到5个设备编译的时候要设置 =2

	private void initLogDir()
	{
		RobotFileUtils.buildDir("/sdcard/PuduRobotLog");
		RobotFileUtils.buildDir("/sdcard/PuduRobotLog/bak");
		RobotFileUtils.buildDir(CanbusDataSaveThread.strCanBusLogPathName);


		RobotFileUtils.buildDir("/sdcard/PuduRobot");
		File file0= new File("/sdcard/PuduRobot/0");
		File file1= new File("/sdcard/PuduRobot/1");
		try {

			if(file0.exists() == false)
			{
				file0.createNewFile();
			}


		} catch (IOException e) {
			e.printStackTrace();
		}

		try {

			if(file1.exists() == false)
			{
				file1.createNewFile();
			}


		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public String getLogPath()
	{
		String path = "/sdcard/PuduRobotLog";
		return path;
	}

	public String getLogBakPath()
	{
		String path = "/sdcard/PuduRobotLog/bak";
		return path;
	}

	private void setRobotSerialID()
	{
		try {
			WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
			WifiInfo info = wifi.getConnectionInfo();
			RobotSerialID = info.getMacAddress();
			RobotSerialID = RobotSerialID.replace(":", "");
		}catch(Exception e){
			e.printStackTrace();
			RobotSerialID = "RobotID-Pudu";
		}
	}

	public String getRobotSerialID()
	{
		return RobotSerialID;
	}

	public void init() {
		// 初始化网络请求
		AsyncHttpClient client = new AsyncHttpClient();
//		PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
//		client.setCookieStore(myCookieStore);
		ApiHttpClient.setHttpClient(client);
//		ApiHttpClient.setCookie(ApiHttpClient.getCookie(this));


	}
	/**
	 * bugly.qq.com 初始化appid 900040028为申请的appid
	 * 第三个参数为SDK调试模式开关，调试模式的行为特性如下：
	 ● 输出详细的Bugly SDK的Log；
	 ● 每一条Crash都会被立即上报；
	 ● 自定义日志将会在Logcat中输出。
	 建议在测试阶段建议设置成true，发布时设置为false。
	 */
	private void initData(){
		CrashReport.initCrashReport(getApplicationContext(), "900040028", true);

		tcpStringEntity.setStr("init from app");
	}
	/**
	 * 开启线程，跑广播
	 */
	private void initThread(){
		//客户端线程，通过广播，接收来自其他设备的Ip
		if (threadIsLived) {
			cThread = new Thread(new ClientThread());
			cThread.start();
			//服务端开启线程，广播不断的发送自己的ip,以便于其他设备可以接收到
			sThread = new Thread(new ServerThread(this));
			sThread.start();
			//tcp接收数据的线程，一旦发现有连接就接收数据
			tcpTherad = new Thread(new TcpReceiverThread());
			tcpTherad.start();

			//日志线程用来循环查询消息队列
			logThread = new LogFileThread();
			logThread.start();

			//0919
			//硬件要求添加保存CAN BUS数据功能线程
			mBusDataSaveThread = new CanbusDataSaveThread();
			mBusDataSaveThread.start();
		}
	}



	public static synchronized App context() {
		return (App) _context;
	}

	public static App getInstance() {
		return instance;

	}

	//当后台程序已经终止资源还匮乏时会调用这个方法。好的应用程序一般会在这个方法里面释放一些不必
	//要的资源来应付当后台程序已经终止，前台应用程序内存还不够时的情况。
	@Override
	public void onLowMemory() {
		super.onLowMemory();
		threadIsLived = false;
		cThread.interrupt();
	}

	// onTerminate 当终止应用程序对象时调用，不保证一定被调用，当程序是被内核终止以便为其他应用程序释放资源，那
	//么将不会提醒，并且不调用应用程序的对象的onTerminate方法而直接终止进程
	@Override
	public void onTerminate() {
		super.onTerminate();
		threadIsLived = false;
		cThread.interrupt();
		sThread.interrupt();
		tcpTherad.interrupt();
		logThread.interrupt();
		SpUtils.set("not_update_this_time",false);
	}

	public void saveApplicationMapData(String jsonMap)
	{
		synchronized(instance){
			RobotFileUtils.writePathFile("/sdcard/PuduRobotMap", "MAP_DATA", jsonMap);
		}
	}

	public void saveApplicationAtlasData(String jsonMap)
	{
		Log.i("App","map:"+jsonMap);
		synchronized(instance){
			Log.i("App","map2:"+jsonMap);
			RobotFileUtils.writePathFile("/sdcard/PuduRobotMap", "ATLAS_DATA", jsonMap);
		}
	}

	public String getApplicationMapData()
	{
		synchronized(instance){
			String data = RobotFileUtils.readPathFile("/sdcard/PuduRobotMap", "MAP_DATA");
			return data;
		}
	}

	public String getApplicationAtlasData()
	{
		synchronized(instance){
			String strMap = RobotFileUtils.readPathFile("/sdcard/PuduRobotMap", "ATLAS_DATA");
			return strMap;
		}
	}

	//0 /sdcard/PuduRobot/TotalMileage/0
	//1 /sdcard/PuduRobot/TotalMileage/1
	public static int mReadFileFlag = 0;
	// Mileage 单位 cm
	// 格式：总里程数 xxx++++\n
	private static Object mTotalMileageLock = new Object();
	public static int totalMiles = 0;
	public void writeTotalMileage(int Mileage)
	{
		if( totalMiles == 0 )
		{
			String strValue = readValidFromtalMileage();
			totalMiles = Integer.parseInt(strValue) ;
		}

		synchronized(mTotalMileageLock) {

			totalMiles += Mileage;

			try {
				String fileName = null;
				if(mReadFileFlag == 0)
				{
					fileName ="/sdcard/PuduRobot/1";
					mReadFileFlag = 1;
				}else{
					fileName ="/sdcard/PuduRobot/0";
					mReadFileFlag = 0;
				}
				RandomAccessFile file = new RandomAccessFile(fileName, "rw");
				file.seek(0);

				String newValueData = String.format("%d++++\n", totalMiles);

				file.write(newValueData.getBytes());

				file.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public String readValidFromtalMileage() {
		synchronized (mTotalMileageLock) {
			try {
				if(mReadFileFlag == 0)
				{
					FileReader fr = new FileReader("/sdcard/PuduRobot/0");
					BufferedReader br = new BufferedReader(fr);
					String str = br.readLine();
					if(str != null && str.indexOf("++++") >= 0)
					{
						str = str.substring(0, str.length() - 4);
						br.close();
						fr.close();
						return str;
					}
					br.close();
					fr.close();
				}

				mReadFileFlag = 1;
				FileReader fr = new FileReader("/sdcard/PuduRobot/1");
				BufferedReader br = new BufferedReader(fr);
				String str = br.readLine();
				if(str != null && str.indexOf("++++") >= 0)
				{
					str = str.substring(0, str.length() - 4);
					br.close();
					fr.close();
					return str;
				}

				br.close();
				fr.close();

				Log.i("Robot", "something error, cant record miles");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "0";
		}
	}

	public void StartCanbusService() {
		Intent bindingIntent = new Intent(this, CANDataService.class);
		startService(bindingIntent);
		bindService(bindingIntent, canbusserviceConnection, Context.BIND_AUTO_CREATE);
	}

	public void StopCanbusService()
	{
		try {
			unbindService(canbusserviceConnection);
			//stop ff
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public CANDataService canbusService;
	private final ServiceConnection canbusserviceConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			Log.i(App.MYTAG, "usbserviceConnection onServiceConnected");
			canbusService = ((CANDataService.CanDataBinder) service).getService();

		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
		}
	};

	public LTSService mMyLtsServer;
	private final ServiceConnection LTSConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName arg0, IBinder arg1) {
			mMyLtsServer = ((LTSService.LTSBinder) arg1).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			mMyLtsServer = null;
		}
	};



	/**
	 * 获取App安装包信息
	 *
	 * @return
	 */
	public PackageInfo getPackageInfo() {
		PackageInfo info = null;
		try {
			info = getPackageManager().getPackageInfo(getPackageName(), 0);
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace(System.err);
		}
		if (info == null)
			info = new PackageInfo();
		return info;
	}


}
